		TITLE GETSEGMT - Copyright (c) SLR Systems 1994

		INCLUDE MACROS
		INCLUDE	SEGMENTS
		INCLUDE	CLASSES
		INCLUDE	MODULES

		PUBLIC	GET_SEGMENT_ENTRY,DEFINE_SEGMENT


		.DATA

		EXTERNDEF	SEG_COMBINE:BYTE,SEG_PLTYPE:BYTE,SYMBOL_TEXT:BYTE,SEG32_FLAGS:BYTE

		EXTERNDEF	SYMBOL_HASH:DWORD,SEG_CLASS_GINDEX:DWORD,SEG_SECTION_GINDEX:DWORD,FIRST_STACK_GINDEX:DWORD
		EXTERNDEF	SEG_FRAME:DWORD,SYMBOL_LENGTH:DWORD

		EXTERNDEF	CLASS_GARRAY:STD_PTR_S,SEGMENT_GARRAY:STD_PTR_S,SEGMOD_GARRAY:STD_PTR_S,MODULE_GARRAY:STD_PTR_S

		EXTERNDEF	CASE_STRING_COMPARE:DWORD


		.CODE	PASS1_TEXT

		EXTERNDEF	WARN_ASCIZ_RET:PROC,DEFINE_CLASS:PROC,INSTALL_SEGMENT:PROC,ALLOC_SEGMENT:PROC
		EXTERNDEF	_find_segat_location:PROC,GET_SM_MODULE:PROC,ERR_ASCIZ_RET:PROC

		EXTERNDEF	SEG_COMMON_ERR:ABS,SEG_STACK_ERR:ABS,MULTIPLE_STACKS_ERR:ABS,USE32_USE16_ERR:ABS


TRY_OVERIDES	PROC
		;
		;STACK OVERIDES ANYTHING LEFT
		;
		;CL IS SEG_COMBINE OF NEW
		;AL IS SEG_COMBINE OF OLD
		;
		CMP	AL,SC_STACK		;OLD TYPE
		JNZ	TCF_11
		MOV	SEG_COMBINE,AL		;WAS STACK, FORCE SAME
		JMP	TCF_19

TCF_11:
		CMP	CL,SC_STACK
		JNZ	TCF_2
		ASSUME	EBX:PTR SEGMENT_STRUCT

		MOV	[EBX]._SEG_COMBINE,SC_STACK
TCF_19:
		CALL	DO_STACK
		MOV	AL,SEG_STACK_ERR
TCF_199:
		LEA	ECX,[EBX]._SEG_TEXT
		CALL	WARN_ASCIZ_RET
		MOV	EAX,EDX
		CMP	EDX,EDX
		RET

TCF_2:
		;
		;OK, TRY COMMON OVERIDES ANY LEFT (PUBLIC)
		;
		CMP	AL,SC_COMMON
		JNZ	TCF_21
		MOV	SEG_COMBINE,AL
		JMP	TCF_29

TCF_21:
		CMP	CL,SC_COMMON
		JZ	TCF_28
		RET

TCF_28:
		MOV	[EBX]._SEG_COMBINE,SC_COMMON
TCF_29:
		MOV	AL,SEG_COMMON_ERR
		JMP	TCF_199

TRY_OVERIDES	ENDP


FOUND_ASEG:
		;
		;FRAME MUST MATCH
		;
		CMP	CL,SC_ABSOLUTE
		MOV	EAX,SEG_FRAME
		JNZ	TRY_NEXT_SEGMENT
		CMP	[EBX]._SEG_FRAME,EAX
		JNZ	TRY_NEXT_SEGMENT
		JMP	FOUND_MATCHING_SEGMENT


GET_SEGMENT_ENTRY PROC
		;
		;FIRST, SCAN LIST OF CLASSES FOR MATCHING CLASS
		;
		;RETURN EAX IS SEGMENT ENTRY, ECX IS PHYS
		;
		CALL	DEFINE_CLASS		;EAX IS CLASS_GINDEX, ECX IS PHYS

		MOV	SEG_CLASS_GINDEX,EAX
DEFINE_SEGMENT::				;CALLED FROM RTCMDLIN
		CALL	INSTALL_SEGMENT 	;EAX IS SEGMENT GINDEX, ECX IS PHYS

		PUSH	EBX
		MOV	EBX,ECX

		MOV	EDX,EAX
		;
		; NEW DECISION CRITERIA:
		;
		;IF ASEG, TARGET MUST ALSO BE ASEG, AND FRAME AND OFFSET MUST
		;MATCH.  IF SO, DO LIKE COMMON...
		;
if	fg_plink
		MOV	AL,[EBX]._SEG_PLTYPE
		MOV	ECX,[EBX]._SEG_SECTION_GINDEX
		MOV	SEG_PLTYPE,AL
		MOV	SEG_SECTION_GINDEX,ECX
endif

FOUND_SEGMENT:
		MOV	AL,[EBX]._SEG_COMBINE
		MOV	CL,SEG_COMBINE

		CMP	AL,SC_ABSOLUTE
		JZ	FOUND_ASEG

		CMP	AL,SC_UNDEFINED
		JZ	FOUND_UNDEFINED

		CMP	CL,SC_PRIVATE		;NEW SEGMENT IS PRIVATE?
		JZ	NEW_SEGMENT		;FORCE NEW SEGMENT

		CMP	CL,AL
		JZ	FOUND_MATCHING_SEGMENT

		CALL	TRY_OVERIDES		;COMMON-VS-STACK-PUBLIC
		JZ	FOUND_MATCHING_SEGMENT
TRY_NEXT_SEGMENT::
		;
		;THIS CAN HAPPEN WHEN A SEGMENT HAS DIFFERENT COMBINE TYPE THAN PREVIOUSLY, OR IS ASEG AND DOESN'T MATCH
		;
		MOV	EAX,[EBX]._SEG_NEXT_HASH_GINDEX		;TRY NEXT ONE IN HASH ORDER

		TEST	EAX,EAX
		JZ	NEW_SEGMENT

		MOV	EDX,EAX
		CONVERT	EBX,EAX,SEGMENT_GARRAY

		MOV	EAX,SYMBOL_HASH
		MOV	ECX,SEG_CLASS_GINDEX

		CMP	[EBX]._SEG_HASH,EAX
		JNZ	TRY_NEXT_SEGMENT

		CMP	[EBX]._SEG_CLASS_GINDEX,ECX
		JNZ	TRY_NEXT_SEGMENT

		PUSHM	EDI,ESI

		MOV	EDI,OFF SYMBOL_TEXT
		MOV	ECX,SYMBOL_LENGTH

		LEA	ESI,[EBX]._SEG_TEXT

		CALL	CASE_STRING_COMPARE

		POPM	ESI,EDI

		JZ	FOUND_SEGMENT

		JMP	TRY_NEXT_SEGMENT

FOUND_UNDEFINED:
		;
		;STORE THIS SEGMENT-COMBINE TYPE
		;
		CMP	CL,SC_ABSOLUTE		;USE THIS UNLESS WE ARE DOING
		JZ	TRY_NEXT_SEGMENT	;A SEGMENT 'AT'
		;
		;SET USE32 IF NEEDED
		;
		MOV	AL,SEG32_FLAGS
		MOV	CH,[EBX]._SEG_32FLAGS

		AND	AL,MASK SEG32_USE32
		MOV	[EBX]._SEG_COMBINE,CL

		OR	CH,AL
		MOV	AL,[EBX]._SEG_ORDER_FLAG

		MOV	[EBX]._SEG_32FLAGS,CH

		TEST	AL,MASK DEF_ORDERED
		JZ	ORDER_SEGMENT

		CMP	CL,SC_STACK		;NOTICE STACK EVEN THOUGH DECLARED IN .DEF FILE
		JNZ	F_U_4

		CALL	DO_STACK
F_U_4:
		MOV	ECX,EBX
		POP	EBX

		MOV	EAX,EDX
		RET

NEW_SEGMENT:
		;
		;OK, NEED TO ALLOCATE A NEW SEGMENT BLOCK
		;
		MOV	EAX,SYMBOL_HASH
		CALL	ALLOC_SEGMENT		;EAX IS GINDEX, ECX IS ADDRESS

		MOV	EBX,ECX
		MOV	EDX,EAX

		MOV	AL,[EBX]._SEG_COMBINE
		MOV	CL,SEG_COMBINE

		CMP	AL,SC_UNDEFINED
		JNZ	FOUND_MATCHING_SEGMENT

		CMP	CL,SC_PRIVATE
		JNZ	FOUND_MATCHING_SEGMENT

		MOV	[EBX]._SEG_COMBINE,CL

FOUND_MATCHING_SEGMENT::
		;
		;DS:BX IS SEGMENT, DX IS LOGICAL
		;
		MOV	CH,[EBX]._SEG_TYPE
		MOV	AL,SEG32_FLAGS

		AND	CH,MASK SEG_CV_TYPES1 + MASK SEG_CV_SYMBOLS1
		MOV	AH,[EBX]._SEG_32FLAGS

		MOV	CL,[EBX]._SEG_ORDER_FLAG
		JNZ	L89$			;IGNORE USE32 PROBLEMS ON CODEVIEW SEGMENTS

		AND	AL,MASK SEG32_USE16 + MASK SEG32_USE32
		JZ	L89$

		TEST	EAX,(MASK SEG32_USE16 + MASK SEG32_USE32) * 256
		JZ	L85$

		XOR	AL,AH

		TEST	AL,MASK SEG32_USE16 + MASK SEG32_USE32
		JZ	L89$

		JMP	L8$

L85$:
		OR	AL,AH

		MOV	[EBX]._SEG_32FLAGS,AL
L89$:
		AND	CL,MASK DEF_ORDERED
		JZ	ORDER_SEGMENT
L9$:
		MOV	ECX,EBX
		POP	EBX
		MOV	EAX,EDX
		RET

L8$:
		PUSHM	ECX
		MOV	AL,USE32_USE16_ERR

		LEA	ECX,[EBX]._SEG_TEXT
		CALL	WARN_ASCIZ_RET

		POPM	ECX
		JMP	L89$

ORDER_SEGMENT:
		;
		;NOT ORDERED IN CLASS YET... DO IT.
		;
		GETT	AL,SKIP_ORDERING	;IF 'ORDER', SKIP LINKING
		MOV	CL,[EBX]._SEG_COMBINE

		OR	AL,AL
		JNZ	L9$

		CMP	CL,SC_ABSOLUTE
		JZ	LINK_ABSOLUTE

		MOV	EAX,[EBX]._SEG_CLASS_GINDEX
		MOV	ECX,EBX
		CONVERT	EBX,EAX,CLASS_GARRAY
		;
		;HERE EDX	IS SEGMENT GINDEX
		;     EBX	IS CLASS PHYSICAL
		;	AL	IS COMBINE TYPE
		;
;ORDER_SEGMENT_ROM:
		;
		;LINK THIS SEGMENT TO CLASS
		;
		ASSUME	EBX:PTR CLASS_STRUCT

		MOV	EAX,[EBX]._C_LAST_SEG_GINDEX
		MOV	[EBX]._C_LAST_SEG_GINDEX,EDX

		TEST	EAX,EAX
		JZ	SEG_FIRST

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,EDX
SEG_FIRST_RET:
		MOV	EBX,ECX
		ASSUME	EBX:PTR SEGMENT_STRUCT
SFR_0:
		CMP	SEG_COMBINE,SC_STACK		;STACK?
		JZ	SFR_2
SFR_1:
		;
		;RETURN AX:BX IS SEGMENT, DX IS LOGICAL
		;
		OR	[EBX]._SEG_ORDER_FLAG,MASK DEF_ORDERED
		MOV	ECX,EBX

		POP	EBX
		MOV	EAX,EDX

		RET

SEG_FIRST:
		ASSUME	EBX:PTR CLASS_STRUCT
		MOV	[EBX]._C_FIRST_SEG_GINDEX,EDX
		JMP	SEG_FIRST_RET

SFR_2:
		CALL	DO_STACK
		JMP	SFR_1

LINK_ABSOLUTE:
		;
		;DX:DS:BX IS SEGMENT, STICK IN ASEG LIST ORDERED...
		;
		PUSHM	EDX
		CALL	_find_segat_location	;RETURN DS:SI AS PLACE TO GET

		POPM	EDX
		;
		; POINTER IN ES:[DI]._SEG_NEXT_SEG,
		; OLD ES:[DI]._SEG_NEXT_SEG BECOMES NEW
		;
		ASSUME	EAX:PTR SEGMENT_STRUCT,EBX:PTR SEGMENT_STRUCT

		MOV	ECX,[EAX]._SEG_NEXT_SEG_GINDEX

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,EDX
		MOV	[EBX]._SEG_NEXT_SEG_GINDEX,ECX

		MOV	EAX,EDX
		JMP	SFR_0

GET_SEGMENT_ENTRY	ENDP


DO_STACK	PROC	NEAR
		;
		;
		;
		MOV	EAX,FIRST_STACK_GINDEX

		TEST	EAX,EAX
		JZ	NEW_STACK

		CMP	EAX,EDX
		JZ	L9$
MULTIPLE_STACKS:
if	fg_rom
		BITT	OUTPUT_ABS			;IGNORE MULTIPLE STACKS FOR HEX OUTPUT
		JNZ	L9$
endif
		CONVERT	EAX,EAX,SEGMENT_GARRAY
		MOV	EAX,[EAX]._SEG_FIRST_SEGMOD_GINDEX
		CONVERT	EAX,EAX,SEGMOD_GARRAY
		CALL	GET_SM_MODULE
		CONVERT	EAX,EAX,MODULE_GARRAY
		ASSUME	EAX:PTR MODULE_STRUCT
		LEA	ECX,[EAX]._M_TEXT
		MOV	AL,MULTIPLE_STACKS_ERR
		CALL	WARN_ASCIZ_RET
		MOV	EAX,EDX
		RET

NEW_STACK:
		MOV	FIRST_STACK_GINDEX,EDX
L9$:
		RET

DO_STACK	ENDP


		END

